//==============================================================================
// Routines to send, receive and parse data from MPExtend
//==============================================================================
                        
#include "MP.h"


//==============================================================================
// function to send MPExtended a request for the list of recordings 
//==============================================================================
extern void __stdcall MP_Extended_request_recordings(int server, char *mod)
{ int iResult,i;
  char str[MAX_STRING],str2[MAX_STRING],str3[MAX_STRING];

  strcpy(str,"GET /MpExtended/TVAccessService/json/GetRecordings?sort=3&order=1 HTTP/1.1\r\n");
  strcat(str,"Host: 127.0.0.1:40505\r\n");
  strcat(str,"Authorization: Basic ");
  strcpy(str2,MP_Global_mUserName); strcat(str2,":"); strcat(str2,MP_Global_mPassword);
  base64_encode(str2, (size_t)(strlen(str2)), (size_t *) &i, str3);
  strcat(str,str3);
  strcat(str,"\r\nAccept: application/json; charset=utf-8\r\n\r\n");
  MP_Send(MPEXTENDED,str);
}



//==============================================================================
// function to send MPExtended a request for the channel data for a channel ID 
//==============================================================================
extern void __stdcall MP_Extended_request_channel(int server, char *mod, int channel)
{ int i;
  char str[MAX_STRING],str2[MAX_STRING],str3[MAX_STRING];

  sprintf(str,"GET /MpExtended/TVAccessService/json/GetChannelBasicById?channelId=%d HTTP/1.1\r\n",channel);
  strcat(str,"Host: 127.0.0.1:40505\r\n");
  strcat(str,"Authorization: Basic ");
  strcpy(str2,MP_Global_mUserName); strcat(str2,":"); strcat(str2,MP_Global_mPassword);
  base64_encode(str2, (size_t)(strlen(str2)), (size_t *) &i, str3);
  strcat(str,str3);
  strcat(str,"\r\nAccept: application/json; charset=utf-8\r\n\r\n");
  MP_Send(MPEXTENDED,str);
}

//
// Wait for and Process returned channel data
//
extern void __stdcall MP_Extended_process_channel(int server,char *mod, int channel)
{  int i,j,clen,tlen,hlen,lptr,nested,iResult;
   char str[MAX_STRING],itagname[MAX_STRING], jtagname[MAX_STRING];
   char recvbuf[MAX_STRING],*rstr;
   time_t tstart,tend,tnow,tduration,tsofar;

   // get the channel daa
   iResult=MP_recv(mod,server, recvbuf, MAX_STRING);
   if (iResult>0) tlen=tlen+iResult;
   else if ( iResult == 0 ) 
     { MP_Global_connected[server]=0; MP_log(mod,"Connection closed in process_MP_Extended_channel"); return; }
   else { MP_Global_connected[server]=0; MP_errlog(mod,"recv failed: in process_MP_Extended_channel"); return; }

   // Check the content length too see if we need to recv further data
   // Note that although the channel message is small, we may have got out of sync and be receiving something much larger
   i=strfindstr(recvbuf,"Content-Length:",15);       
   if (i<0) { MP_errlog(mod,"No Content-Length"); return; }
   sscanf(&recvbuf[i],"%*s%d",&clen);
   sprintf(str,"Content-Length: %d",clen);
   MP_logl(3,mod,str);
   // find the end of the header
   hlen=i;
   while ( (recvbuf[hlen]!='\0') && (recvbuf[hlen]!='[') && (recvbuf[hlen]!='{') ) hlen=hlen+1;
   // if rlen=>(clen+hlen) then we got it all
   sprintf(str,"Message sizes: iResult=%d, clen=%d, hlen=%d",iResult,clen,hlen);
   MP_logl(3,mod,str);

   // make sure we have the whole message
   tlen=iResult;
   while (tlen<(clen+hlen))
     { MP_logl(3,mod,"Waiting for extra data in process_MP_Extended_channel");
       iResult=MP_recv(mod,server, &recvbuf[tlen], MAX_STRING-tlen);
       if (iResult>0) tlen=tlen+iResult;
       else if ( iResult == 0 ) 
         { MP_Global_connected[server]=0; MP_log(mod,"Connection closed in process_MP_Extended_channel"); return; }
       else { MP_Global_connected[server]=0; MP_errlog(mod,"recv failed: in process_MP_Extended_channel"); return; }
     }
//
// Okay we have all the data now so process it if it's not empty (i.e. []   
//
   if (clen>2) 
     { rstr=&recvbuf[tlen-clen]; // point to the Json data in the message
       rstr[clen]=0;
       MP_log(mod,rstr); 
       
       lptr=0; sprintf(itagname,"Channel%d",channel); nested=strlen(itagname);
       i=strfind(rstr,'{',lptr);  
       // Make sure it's the right message
       if (i>0) { lptr=i-1; 
                  if (!strncmp(&rstr[lptr+2],"DisplayName",11))     // tags will be Channeln.Something
                    { MP_Parse_item(mod,itagname,rstr,&lptr,&nested); } // it's the right message so get the tags
                  else { MP_log(mod,"Not a channel message"); return; }
                }
     }
   else MP_log(mod,"Empty channel Message"); 
}     


//==============================================================================
// Function to proces the returned data from MPExtended
//==============================================================================
                             
extern void __stdcall MP_Extended_process_recordings(int server,char *mod, char *recvbuf, int rlen)
{  int i,j,clen,lptr,nested,num_recordings,tvchannelid,iResult,tlen,hlen;
   char str[MAX_STRING],*rstr,itagname[MAX_STRING], jtagname[MAX_STRING], rtagname[MAX_STRING];
   time_t tstart,tend,tnow,tduration,tsofar;

   num_recordings=0;
   i=strfindstr(recvbuf,"Content-Length:",15);       
   if (i<0) { MP_errlog(mod,"No Content-Length"); return; }
   sscanf(&recvbuf[i],"%*s%d",&clen);
   sprintf(str,"Content-Length: %d",clen);
   MP_logl(3,mod,str);

   // find the end of the header
   hlen=i;
   while ( (recvbuf[hlen]!='\0') && (recvbuf[hlen]!='[') && (recvbuf[hlen]!='{') ) hlen=hlen+1;

   // if rlen=>(clen+hlen) then we got it all
   sprintf(str,"Message sizes: rlen=%d, clen=%d, hlen=%d",rlen,clen,hlen);
   MP_logl(3,mod,str);
   // make sure we have the whole message
   tlen=rlen;
   while (tlen<(clen+hlen))
     { MP_logl(3,mod,"Waiting for extra data in process_MP_Extended");
       iResult=MP_recv(mod,server, &recvbuf[tlen], MAX_BUFLEN-tlen);
       if (iResult>0) tlen=tlen+iResult;
       else if ( iResult == 0 ) 
         { MP_Global_connected[server]=0; MP_logl(3,mod,"Connection closed in process_MP_Extended"); return; }
       else { MP_Global_connected[server]=0; MP_errlog(mod,"recv failed: in process_MP_Extended"); return; }
     }
   
   clen=clen-2;    // remove []
   if (clen>0) 
     { //strncpy(rstr,&recvbuf[tlen-clen-2],clen); 
       rstr=&recvbuf[tlen-clen-2];
       rstr[clen+1]=0;
       MP_log(mod,rstr); 

       lptr=0; 
       while (lptr<strlen(rstr))
         { i=strfind(rstr,'{',lptr);  // is there more?
           if (i>0) 
             { lptr=i-1; 
               if (!strncmp(&rstr[lptr+2],"Description",11))
                 { num_recordings=num_recordings+1; 
                   if (num_recordings<MAX_RECORDINGS) 
                     { sprintf(itagname,"Rec%d",num_recordings); nested=strlen(itagname);
                       MP_lock(); MP_Parse_item(mod,itagname,rstr,&lptr,&nested); MP_unlock(); 
                     }
                   else { MP_log(mod,"Not a recordings message"); return; }
                 }
               else break;
             }  
         }
       MP_put_tag("NRecordings", 1, num_recordings, MP_nr_to_string(num_recordings));
     }
   else
     { MP_log(mod,"Empty Message"); 
     }
     
//
// Now work out what is being recorded
//
  MP_lock();
  j=0;
  if (num_recordings>0)
    { for (i=0;i<num_recordings;i++)
        { sprintf(rtagname,"Rec%d",i+1); 
          sprintf(itagname,"%s.IsRecording",rtagname);
          if (!strncmp(MP_gtag(itagname),"true",4))
            { // found a current recording
              j=j+1;
              MP_put_tag("IsRecording",1,1,"true");

              sprintf(jtagname,"Recording%d.Entry",j);
              MP_put_tag(jtagname, 0, i+1, MP_nr_to_string(i+1));
              
              sprintf(jtagname,"Recording%d.IsRecording",j);
              MP_put_tag(jtagname, 1, 0, "true");

              sprintf(itagname,"%s.Title",rtagname);
              sprintf(jtagname,"Recording%d.Title",j);
              MP_put_tag(jtagname, 1, 0, MP_gtag(itagname));

              sprintf(itagname,"%s.StartTime",rtagname);; 
              sprintf(jtagname,"Recording%d.StartTime",j);
              MP_put_tag(jtagname, 3, 0, MP_gtag(itagname));
              tstart=MP_gttag(itagname);
 
              sprintf(itagname,"%s.EndTime",rtagname); 
              sprintf(jtagname,"Recording%d.EndTime",j);
              MP_put_tag(jtagname, 3, 0, MP_gtag(itagname));
              tend=MP_gttag(itagname);

              // work out the so far/duration from the two times and the time now
              tnow=time( NULL );                 // get the time 
              tsofar=tnow-tstart; if (tsofar<0) tsofar=0; if (tsofar>(12*60*60)) tsofar=0;  // whats up with tsofar
              tduration=tend-tstart; if (tduration<0) tduration=0;
              sprintf(str,"start=%d, end=%d, duration=%d, now=%d",tstart,tend,tduration,tnow);
              MP_log(mod,str);
              sprintf(jtagname,"Recording%d.SoFar",j);
              MP_one_time_fmt(str,"%d:%02d:%02d",tsofar);
              MP_put_tag(jtagname, 3, 0, str);
              sprintf(jtagname,"Recording%d.Duration",j); // This is a wastw of time since start time = end time
              MP_one_time_fmt(str,"%d:%02d:%02d",tduration);
              MP_put_tag(jtagname, 3, 0, str);
              
              // now check if we have TV channel info for this channel ID
              sprintf(itagname,"%s.IdChannel",rtagname); 
              sprintf(jtagname,"Recording%d.IdChannel",j);
              tvchannelid=MP_itag(itagname);
              MP_put_tag(jtagname, 0, 0, MP_gtag(itagname));

              sprintf(itagname,"Channel%d.DisplayName",tvchannelid);
              strcpy(str,MP_gtag(itagname));
              if (strlen(str)==0) 
                { MP_Extended_request_channel(server, mod, tvchannelid); 
                  MP_Extended_process_channel(server, mod, tvchannelid);
                }
              sprintf(jtagname,"Recording%d.ChannelName",j);
              MP_put_tag(jtagname, 0, 0, MP_gtag(itagname));
            }
        }
      if (j>0) MP_put_tag("Recordings", 1, j, MP_nr_to_string(j));
      else { MP_put_tag("Recordings", 1, 0, "None");  MP_put_tag("IsRecording",1,0,"false"); }
      MP_put_tag("IRecordings", 0, j, itoa(j, str, 10));
    }
  else MP_put_tag("IsRecording",1,0,"false");
  // set all the other recordings off
  for (i=(MP_itag("Recordings")+1); i<10; i++)
    { sprintf(jtagname,"Recording%d.IsRecording",i);
      MP_put_tag(jtagname, 1, 0, "false");
    }
  MP_unlock();
}

